package com.scalar.chiptrack.adaptor.osep;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.ParserException;
import com.scalar.chiptrack.adaptor.InventoryLot;
import com.scalar.chiptrack.adaptor.dao.InventoryLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: Sudhakar
 * Date: Aug 2, 2007
 * Time: 4:37:47 PM
 */
public class OSEPDieBankDataParser extends JobHandler implements AdaptorConstants
{

    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;
    private HashMap m_dieBankDataMap        = new HashMap();

    public OSEPDieBankDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir(VENDOR_NAME_OSEP, INVENTORY_TYPE_DIE_BANK);
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_OSEP );
            OsepDAO.setLogger(m_parserLogger);
            AdaptorUtils.setLogger( m_parserLogger);
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading OSEP Die Bank output directory details from database, Exception: " + se);
            throw se;
        }
    }

    public static void main( String args[] ) throws Exception
    {
        new OSEPDieBankDataParser().execute();
    }

    public void execute() throws Exception
    {
        AdaptorUtils.printHeader(VENDOR_NAME_OSEP + " "+LOCATION_TYPE_DIE_BANK, CONSTANT_PARSER );

        File doneDestDir = new File( m_dataOutputDir + "/done");

        File tsmcWipDataoutDir = new File( m_dataOutputDir );

        File[] fileList = tsmcWipDataoutDir.listFiles();

        if ( ( fileList == null ) || ( fileList.length <= 3 ) )
        {
            log( "No file found in directory: " + tsmcWipDataoutDir );
            System.out.println( "No file found in directory: " + tsmcWipDataoutDir );
            throw new ScalarException( "No file found in directory: " + tsmcWipDataoutDir + "----\n\n" );

        }

        String fileName             = null;
        String tempName             = null;
        ArrayList osepDieBankList   = null;

        ArrayList successFileList   = new ArrayList();
        boolean success             = true;

        try
        {
            for ( int i = 0; i < fileList.length; i++ )
            {

                if ( fileList[i].isDirectory() == true )
                {
                    continue;
                }

                tempName = fileList[i].getName();
                fileName = fileList[i].getAbsolutePath();

               if ( ( tempName != null ) && ( tempName.trim().startsWith( OSEPDieBankFTPAdaptor.FILE_NAME_WIP ) ) )
                {
                    try
                    {
                        osepDieBankList = parseDieBankInfo( fileName );
                        segrigateDieBankInfo(osepDieBankList);
                        successFileList.add( fileList[i] );
                    }
                    catch ( Exception e )
                    {
                        success = false;
                        log( "Exception while parsing and storing file: " + fileName + "\nException: " + e );
                        e.printStackTrace();
                        throw e;
                    }
                }

            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! While parsing and storing File " + e );
            e.printStackTrace();
            throw e;
        }

        //Updating the OSEP Die Bank Lot Information*/
        try
        {
            // Step 2
            // Save Finished Goods Information
            if (m_dieBankDataMap.isEmpty() == false)
            {
                log(" Updating OSEP Die Bank Lot Information");
                OsepDAO.saveOSEPDieBankLot(null, m_dieBankDataMap.values().iterator());
            }
            else
            {
                InventoryLotDAO.closeInventoryLot(null, INVENTORY_TYPE_DIE_BANK, VENDOR_NAME_OSEP);
            }
            m_dieBankDataMap.clear();
            m_dieBankDataMap = null;
            success = true;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log("ERROR!! ERROR!! ERROR!! Could not update Die Bank Lot information into database: " + se);
            throw se;
        }

        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications(VENDOR_NAME_OSEP, true, true, true);

        // To Close All Drop Out Lots
        AdaptorDAO.closeDropOutLots(VENDOR_NAME_OSEP);

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( OSEPDieBankFTPAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, OSEPDieBankFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, OSEPDieBankFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }
       // Step 7
       // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir);
       }
    }
    /**
     *
     * @param fileName
     * @return
     * @throws Exception
     */
    private  ArrayList parseDieBankInfo( String fileName ) throws Exception
    {
        if ( fileName == null )
        {
            throw new ScalarException( "Filename argument is null" );
        }

        ArrayList dieBankInfoList   = new ArrayList();
        BufferedReader fileReader   = null;

        try
        {
            File wipInfoFile = new File( fileName );
            if ( wipInfoFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            System.out.println( "Found " + fileName );
            System.out.println( "Parsing the file for OSEP Die Bank Information..." );

            fileReader = new BufferedReader( new FileReader( wipInfoFile ) );

            String line = null;
            OSEPDieBankStatus dieBankInfo = null;
            ArrayList errors = new ArrayList();

            for( int i = 0; i < 6 ; i++)
            {
               fileReader.readLine();
            }

            while ( ( line = fileReader.readLine() ) != null )
            {
                try
                {
                    dieBankInfo = parseDieBankInfoLine( line );
                }
                catch ( ParserException pe )
                {
                    dieBankInfo = null;
                    errors.add( pe.getMessage() );
                }
                if ( dieBankInfo != null )
                {
                    dieBankInfoList.add(dieBankInfo);
                }
            }

            fileReader.close();
            fileReader = null;

            System.out.println( "Done parsing.." );

            if ( errors.isEmpty() == false )
            {   // Parser Errors, Send mail to ChipTrac System Administrator
                System.out.println( "\nFound errors... notifying system administrator..." );
                System.out.println( "done\n" );
            }
        }
        finally
        {
            if ( fileReader != null )
            {
                try
                {
                    fileReader.close();
                }
                catch ( IOException ignore )
                {
                }
            }
        }

        return dieBankInfoList;
    }
    /**
     *
     * @param line
     * @return
     * @throws ParserException
     */
    private OSEPDieBankStatus parseDieBankInfoLine(String line) throws ParserException
    {

        OSEPDieBankStatus dieBankInfo = null;

        if ((line == null) || (line.startsWith("---")) || (line.trim().length() < 25 /*min length*/))
        {
            return dieBankInfo;
        }

        try
        {
            String[] token = line.split(",");

            dieBankInfo = new OSEPDieBankStatus();

            for (int x = 0; x < token.length; x++)
            {
                if (token[x] != null && token[x].trim().length() > 0)
                {
                    switch (x)
                    {
                        case 0:
                            dieBankInfo.setItem(token[x].trim());
                            break;
                        case 1:
                            dieBankInfo.setDateReceived(token[x].trim());
                            break;
                        case 2:
                            dieBankInfo.setFabLot(token[x].trim());
                            break;
                        case 3:
                            dieBankInfo.setOrgThickness(token[x].trim());
                            break;
                        case 4:
                            dieBankInfo.setPartialThickness(token[x].trim());
                            break;
                        case 5:
                            dieBankInfo.setLotId(token[x].trim());
                            break;
                        case 6:
                            dieBankInfo.setDevice(token[x].trim());
                            break;
                        case 7:
                            dieBankInfo.setWaferQty(token[x].trim());
                            break;
                        case 8:
                            dieBankInfo.setDieQty(token[x].trim());
                            break;
                        case 9:
                            dieBankInfo.setInvoiceNumber(token[x].trim());
                            break;
                    }
                }
            }
        }
        catch (Exception e)
        {
            System.out.println("Exception while parsing  OSEP Die Bank Info: " + e);
            System.out.println("Line: " + line);
            throw new ParserException("Exception while parsing OSEP Die Bank Info: " + e + "\nLine: " + line, e);
        }

        return dieBankInfo;
    }

    /**
     *
     * @param dieBankList
     */
    public void segrigateDieBankInfo( ArrayList dieBankList)
    {
        OSEPDieBankStatus dieBankInfo   = null;
        String lotNumber                = null;
        String partNumber               = null;
        InventoryLot inventoryLot       = null;

        Iterator dieBankIterator = dieBankList.iterator();

        while( dieBankIterator.hasNext())
        {
            dieBankInfo = (OSEPDieBankStatus) dieBankIterator.next();

            lotNumber   = dieBankInfo.getFabLot();
            partNumber  = dieBankInfo.getDevice();

            if (lotNumber != null && partNumber != null)
            {
                inventoryLot = (InventoryLot) m_dieBankDataMap.get(lotNumber + partNumber);

                if (inventoryLot == null)
                {
                    inventoryLot = new InventoryLot(VENDOR_NAME_OSEP, INVENTORY_TYPE_DIE_BANK);
                    m_dieBankDataMap.put(lotNumber + partNumber, inventoryLot);
                }

                int quantity = 0;
                if (inventoryLot.getQtyIn() != null)
                {
                    try
                    {
                        quantity = Integer.parseInt(inventoryLot.getQtyIn());
                    }
                    catch (NumberFormatException npe)
                    {
                    }
                    try
                    {
                        quantity += Integer.parseInt(dieBankInfo.getDieQty());
                    }
                    catch (NumberFormatException npe) {
                    }
                }
                else
                {
                    try
                    {
                        quantity = Integer.parseInt(dieBankInfo.getDieQty());
                    }
                    catch (NumberFormatException npe) {
                    }
                }

                String dateIn = null;
                String receiveDate = null;
                //Max Date is Considering as DATE IN
                if (inventoryLot.getDateIn() != null)
                {
                    dateIn = inventoryLot.getDateIn();
                }
                if (dieBankInfo.getDateReceived() != null && dieBankInfo.getDateReceived().trim().length() > 0)
                {
                    receiveDate = dieBankInfo.getDateReceived();
                }
                if ((receiveDate != null) && (dateIn != null))
                {
                    java.util.Date tempDate1 = StringUtils.getSQLDate(receiveDate, "MM/dd/yyyy");
                    java.util.Date tempDate2 = StringUtils.getSQLDate(dateIn, "MM/dd/yyyy");
                    if (tempDate1 != null && tempDate2 != null)
                    {
                        if (tempDate1.compareTo(tempDate2) < 0)
                        {
                            receiveDate = dateIn;
                        }
                    }
                }
                if( quantity > 0 )
                {
                    inventoryLot.setLotNumber(lotNumber);
                    inventoryLot.setPartNumber(partNumber);
                    inventoryLot.setFabLotNumber(lotNumber);
                    inventoryLot.setQtyIn(quantity + "");
                    inventoryLot.setDateIn(receiveDate);
                    inventoryLot.setStatus(LOT_STATUS_RUNNING);
                    inventoryLot.setVendorName(VENDOR_NAME_OSEP);
                    inventoryLot.setLotCategory(LOT_CATEGORY_TYPE_PROD);
                }
            }
        }

    }

    /**
     *
     * @param message
     */
    private static void log( String message )
    {

        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }

}
